package org.apache.ocean;

import java.util.Date;

import org.apache.commons.lang.StringUtils;
import org.jdom.Element;

import com.ibm.icu.text.DecimalFormat;

/**
 *
 * @author jasonr
 */
public class OceanDocument extends NamedList<String,Object> implements CElement {
	public OceanDocument() {}
	
	public OceanDocument(Element root) throws Exception {
    for (Element element : XMLUtil.getChildren(root)) {
      String name = element.getName();
      String type = element.getAttributeValue("type");
      Object value = getObject(type, element.getText());
      add(name, value);
    }
  }
	
  public static Object getObject(String type, String text) throws Exception {
    if (StringUtils.equals("long", type)) {
      return new CLong(text);
    } else if (StringUtils.equals("date", type)) {
      return ClusterUtil.parseDate(text);
    } else if (StringUtils.equals("string", type)) {
      return text;
    } else if (StringUtils.equals("double", type)) {
      return new CDouble(text);
    } else if (StringUtils.equals("transactionid", type)) {
      return new TransactionID(text);
    } 
    throw new Exception("unknown type: "+type);
  }

  public Element toElement() throws Exception {
  	DecimalFormat decimalFormat = new DecimalFormat("###0.000000");
    Element root = new Element("document");
    for (NamedList.Entry<String,Object> entry : getEntries()) {
      Element element = getElement(entry, decimalFormat);
      if (element != null) {
        root.addContent(element);
      }
    }
    return root;
  }

  public static Element getElement(NamedList.Entry<String,Object> entry, DecimalFormat decimalFormat) throws Exception {
    if (entry.value == null) {
      return null;
    }
    String type = null;
    String text = null;
    if (entry.value instanceof Date) {
      type = "date";
      text = ClusterUtil.toDateString((Date)entry.value);
    } else if (entry.value instanceof CLong) {
      type = "long";
      text = entry.value.toString();
    } else if (entry.value instanceof CDouble) {
    	CDouble cdouble = (CDouble)entry.value;
      type = "double";
      text = decimalFormat.format(cdouble.value);
    } else if (entry.value instanceof TransactionID) {
      type = "transactionid";
      text = entry.value.toString();
    } else if (entry.value instanceof String) {
      type = "string";
      text = (String)entry.value;
    } else {
      if (StringUtils.isBlank(type)) {
        throw new Exception("unknown type: " + entry.value.getClass().getName());
      }
    }
    Element element = new Element(entry.key);
    element.setAttribute("type",type);
    element.setText(text);
    return element;
  }
}
